package com.aspirecn.core.datacache;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.aspirecn.core.commons.Configuration;
import com.aspirecn.core.commons.IPUtils;
import com.aspirecn.core.object.IP;
import com.aspirecn.core.object.IPRange;

/**
 * IP网关缓存，仅针对移动的cmwap和cmnet
 * 单IP数据保存在map中
 * IP范围放在列表中
 * 
 * @author wangxinning
 * 
 */
public class IPGatewayCache extends BaseLocalCache {

	public final static Logger logger = Logger.getLogger(IPGatewayCache.class);

	private static IPGatewayCache instance = new IPGatewayCache();
	//范围数据保存在这里
	private List<IPRange> ipGatewayList = new ArrayList<IPRange>();
	//单IP提速
	private Map<String,IPRange> ipGatewayMap = new HashMap<String,IPRange>();

	public int getCount()
	{
		return ipGatewayList.size() + ipGatewayMap.size();
	}
	
	private IPGatewayCache() {
		this.dataFile = new File(Configuration.getInstance()
				.getDownloadFilePath() + File.separator + "gateway.json");
		load();
	}

	public static IPGatewayCache getInstance() {
		return instance;
	}

	@Override
	public void load() {

		if( !loading.getAndSet(true) && Configuration.getInstance().switchIPCache() && this.dataFile.exists() )
		{
		
		long start = System.currentTimeMillis();
		
		try {
			if (this.ipGatewayList.isEmpty() && this.dataFile.exists()) {
				
				List<IPRange> tempIpGatewayList = new ArrayList<IPRange>();
				
				String contentString = FileUtils
						.readFileToString(this.dataFile);
				
				String cmnetString = StringUtils.substringBetween(contentString, "<!--cmnet-->");
				String cmwapString = StringUtils.substringBetween(contentString, "<!--cmwap-->");
				
				//加载cmwap
				JSONArray jsonArray = JSONArray.fromObject(cmwapString);
				ListIterator<?> ite = jsonArray.listIterator();
				while (ite.hasNext()) {
					String objstr = ite.next().toString();
					JSONObject jsonobj = JSONObject.fromObject(objstr);

					String ip = StringUtils.trimToEmpty(jsonobj.getString("ip"));					
					
					long[] iprange = IPUtils.getIPRange(ip);
					
					IPRange range = new IPRange();
					range.setStartIpNum(iprange[0]);
					range.setEndIpNum(iprange[1]);
					range.setGateway(IP.CMWAP_GATEWAY);	
					tempIpGatewayList.add(range);
				}
				
				//加载cmnet
				jsonArray = JSONArray.fromObject(cmnetString);
				ite = jsonArray.listIterator();
				while (ite.hasNext()) {
					String objstr = ite.next().toString();
					JSONObject jsonobj = JSONObject.fromObject(objstr);

					String ip = StringUtils.trimToEmpty(jsonobj.getString("ip"));
					long[] iprange = IPUtils.getIPRange(ip);
					
					if( iprange != null && iprange.length==2 )
					{
						IPRange range = new IPRange();
						range.setStartIpNum(iprange[0]);
						range.setEndIpNum(iprange[1]);
						range.setGateway(IP.CMNET_GATEWAY);
						tempIpGatewayList.add(range);
						
						//System.out.println( range );
					}
				}
				
				//排序，按单wap，单net，多wap，多net排序
				//先单个，在范围，先cmwap，在cmnet
				for (IPRange tempIPRange : tempIpGatewayList) {					
					if( tempIPRange.getStartIpNum().longValue() == tempIPRange.getEndIpNum().longValue() && tempIPRange.getGateway() == IP.CMWAP_GATEWAY )
					{
						//tempIpGatewayList.add(tempIPRange);
						String key = Long.toString(tempIPRange.getStartIpNum().longValue());
						if( ipGatewayMap.get(key) == null )
						{
							ipGatewayMap.put(key, tempIPRange);
						}
					}
				}
				
				for (IPRange tempIPRange : tempIpGatewayList) {
					
					if( tempIPRange.getStartIpNum().longValue() == tempIPRange.getEndIpNum().longValue() && tempIPRange.getGateway() == IP.CMNET_GATEWAY )
					{
						//tempIpGatewayList.add(tempIPRange);	
						String key = Long.toString(tempIPRange.getStartIpNum().longValue());
						if( ipGatewayMap.get(key) == null )
						{
							ipGatewayMap.put(key, tempIPRange);
						}
					}
				}
				
				for (IPRange tempIPRange : tempIpGatewayList) {
					
					if( tempIPRange.getStartIpNum().longValue() != tempIPRange.getEndIpNum().longValue() && tempIPRange.getGateway() == IP.CMWAP_GATEWAY )
					{
						ipGatewayList.add(tempIPRange);
					}
				}
				
				for (IPRange tempIPRange : tempIpGatewayList) {
					
					if( tempIPRange.getStartIpNum().longValue() != tempIPRange.getEndIpNum().longValue() && tempIPRange.getGateway() == IP.CMNET_GATEWAY )
					{
						ipGatewayList.add(tempIPRange);
					}
				}
			}
		} catch (Exception e) {
			loading.set(false);
			logger.error("ip网关数据加载失败", e);
			return;
		}

		loading.set(false);
		long end = System.currentTimeMillis();
		updateFileDownloadTime();
		logger.info("IP网关信息加载完成，time=" + (end - start) + "ms,size=" + ipGatewayList.size());
		
	}
	else
	{
		logger.info( "配置关闭，IP网关信息未加载" );
	}
		
		loading.set(false);
	}

	@Override
	public void clear() {

		ipGatewayList.clear();
		ipGatewayMap.clear();
	}

	@Override
	public void reload() {

		if (this.fileIsChange()) {
			this.clear();
			this.load();
		}
		else
		{
			logger.info( "没变化，IP网关信息未加载" );
		}
	}

	private IP search(long longIP) {
		
		if( this.isLoading() )
		{
			return null;
		}
		
		String ipStr = IPUtils.longToIP(longIP);
		
		long start = System.currentTimeMillis();
		IP ip = null;
		
		//System.out.println( ipGatewayMap.size() );

		//先map里面找
		String key = Long.toString(longIP);
		IPRange tempIPRange1 = ipGatewayMap.get(key);
		if( tempIPRange1 != null )
		{
			//System.out.println( tempIPRange1 );
			ip = new IP();
			ip.setIpAddress(ipStr);
			ip.setGateway(tempIPRange1.getGateway());
		}
		
		int logtimes = 0;	
		if( ip == null )
		{
			for (IPRange tempIPRange : ipGatewayList) {
				logtimes++;
				
				if (longIP >= tempIPRange.getStartIpNum().longValue()
						&& longIP <= tempIPRange.getEndIpNum().longValue()) {
					ip = new IP();
					ip.setIpAddress(ipStr);
					ip.setGateway(tempIPRange.getGateway());
					break;
				}
			}
		}
		
		
//		//先单个，在范围，先cmwap，在cmnet
//		if( ip == null )//cmwap单个ip
//		{
//			for (IPRange tempIPRange : ipGatewayList) {
//				logtimes++;
//				
//				if( tempIPRange.getStartIpNum().longValue() == tempIPRange.getEndIpNum().longValue() && tempIPRange.getGateway() == IP.CMWAP_GATEWAY )
//				{
//					if (longIP >= tempIPRange.getStartIpNum()
//							&& longIP <= tempIPRange.getEndIpNum()) {
//						
//						ip = new IP();
//						ip.setIpAddress(ipStr);
//						ip.setGateway(tempIPRange.getGateway());
//						break;
//					}
//				}
//			}
//		}
//		
//		if( ip == null )//cmnet单个ip
//		{
//			for (IPRange tempIPRange : ipGatewayList) {
//				logtimes++;
//				
//				if( tempIPRange.getStartIpNum().longValue() == tempIPRange.getEndIpNum().longValue() && tempIPRange.getGateway() == IP.CMNET_GATEWAY )
//				{
//					
//					
//					if (longIP >= tempIPRange.getStartIpNum()
//							&& longIP <= tempIPRange.getEndIpNum()) {
//						ip = new IP();
//						ip.setIpAddress(ipStr);
//						ip.setGateway(tempIPRange.getGateway());
//						break;
//					}
//				}
//			}
//		}
//		
//		if( ip == null )//cmwap范围ip
//		{
//			for (IPRange tempIPRange : ipGatewayList) {
//				logtimes++;
//				
//				if( tempIPRange.getStartIpNum().longValue() != tempIPRange.getEndIpNum().longValue() && tempIPRange.getGateway() == IP.CMWAP_GATEWAY )
//				{
//					if (longIP >= tempIPRange.getStartIpNum()
//							&& longIP <= tempIPRange.getEndIpNum()) {
//												
//						ip = new IP();
//						ip.setIpAddress(ipStr);
//						ip.setGateway(tempIPRange.getGateway());
//						break;
//					}
//				}
//			}
//		}
//		
//		if( ip == null )//cmnet范围ip
//		{
//			for (IPRange tempIPRange : ipGatewayList) {
//				logtimes++;
//				
//				if( tempIPRange.getStartIpNum().longValue() != tempIPRange.getEndIpNum().longValue() && tempIPRange.getGateway() == IP.CMNET_GATEWAY )
//				{
//					if (longIP >= tempIPRange.getStartIpNum()
//							&& longIP <= tempIPRange.getEndIpNum()) {
//						ip = new IP();
//						ip.setIpAddress(ipStr);
//						ip.setGateway(tempIPRange.getGateway());
//						break;
//					}
//				}
//			}
//		}

		long end = System.currentTimeMillis();
		logger.debug("搜索IP网关，比较次数：" + logtimes + ";times=" + (end - start)
				+ "ms!ip=" +ipStr);
		return ip;
	}

	public IP search(String ip) {
		long ipLong = IPUtils.ipToLong(ip);
		return search(ipLong);
	}

	public static void main(String[] args) {
		IPGatewayCache ipRangeCache = IPGatewayCache.getInstance();
		System.out.println(ipRangeCache.search("183.220.254.138"));
		// System.out.println( IPUtils.longToIP(3670951181L) );
	}
}
